<template>
    <div class="codeView" @click="createCode">
        <canvas id="canvas" :width="contentWidth" :height="contentHeight"></canvas>
    </div>
</template>

<script>
export default {
    data(){
        return {
            contentWidth:120,
            contentHeight:34,
            identifyCode:''
        }
    },
    mounted(){
        this.createCode()
    },
    methods:{
        createCode(){
            const len = 4 //验证码长度
            const codeList = []
            const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz01234569' //随机数
            const charsLen = chars.length 

            for(let i=0; i < len;i++){
                codeList.push(chars.charAt(Math.floor(Math.random()*charsLen))) //获取随机数的索引 0~61
            }
            this.identifyCode = codeList.join('') //用于校验验证码
            this.$emit('getIdentifyCode',this.identifyCode.toLowerCase())
            this.drawPic()
        },
        //生成随机数
        randomNum(min,max){
            return Math.floor(Math.random() * (max - min) + min)
        },
        // 生成一个随机的颜色
        randomColor(min,max){
            const r = this.randomNum(min,max)
            const g = this.randomNum(min,max)
            const b = this.randomNum(min,max)
            return `rgb(${r},${g},${b})`
        },
        //画布
        drawPic(){
            const canvas = document.getElementById('canvas')
            const ctx = canvas.getContext('2d')
            ctx.textBaseLine = 'bottom'
            //绘制背景
            ctx.fillStyle = this.randomColor(255,255)
            ctx.fillRect(0,0,this.contentWidth,this.contentHeight)
            //绘制文字
            for(let i=0;i<this.identifyCode.length;i++){
                this.drawText(ctx,this.identifyCode[i],i)
            }
            this.drawLine(ctx)
            this.drawDot(ctx)
        },
        drawText(ctx,txt,i){
            ctx.fillStyle = this.randomColor(0,100)
            ctx.font = this.randomNum(25,30) + 'px SimHei'
            const x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
            const y = this.randomNum(25,this.contentHeight - 5)
            let deg = this.randomNum(-45,45)
            // 修改坐标原点和旋转角度
            ctx.translate(x, y)
            ctx.rotate((deg * Math.PI) / 180)
            ctx.fillText(txt, 0, 0)
            // 恢复坐标原点和旋转角度
            ctx.rotate((-deg * Math.PI) / 180)
            ctx.translate(-x, -y)
        },
        //绘制干扰线
        drawLine(ctx){
            for(let i=0;i<5;i++){
                ctx.strokeStyle = this.randomColor(100,255)
                ctx.beginPath()
                ctx.moveTo(this.randomNum(0,this.contentWidth),this.randomNum(0,this.contentHeight))
                ctx.lineTo(this.randomNum(0,this.contentWidth),this.randomNum(0,this.contentHeight))
                ctx.stroke()
            }
        },
        //绘制干扰点
        drawDot(ctx){
            for(let i=0;i<80;i++){
                ctx.fillStyle = this.randomColor(0,255);
                ctx.beginPath()
                ctx.arc(
                    this.randomNum(0,this.contentWidth),
                    this.randomNum(0,this.contentHeight),
                    1,
                    0,
                    2*Math.PI
                )
                ctx.fill()
            }
        }
    }   
}
</script>

<style scoped>
.codeView{
    display: inline-block;
    cursor: pointer;
}
.codeView canvas{
    margin:1px 0 0 16px;
}

</style>